package com.terrace.core.utils.validation;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.terrace.core.constant.StatusConstant;
import com.terrace.core.utils.RegularUtils;
import com.terrace.core.exception.ValidationException;
import com.terrace.core.utils.reflect.ObjectPropertyHelper;
import com.terrace.core.utils.validation.annotation.FieldValid;

/**
 * 验证帮助类
 * @author jiangyg
 *
 */
public class ValidationHelper implements Validator {
	
	/**
	 * 日志
	 */
	private static final Logger logger = LoggerFactory.getLogger(ValidationHelper.class);
	
	/**
	 * 实体对象
	 */
	private Object obj;
	
	/**
	 * 对象属性工具
	 */
	private ObjectPropertyHelper oph;
	
	/**
	 * 错误信息，key属性名，value属性值
	 */
	private Map<String, String> errors = new ConcurrentHashMap<String, String>();
	
	private ValidationHelper() {
	}
	
	private ValidationHelper(Object obj) {
		this.obj = obj;
	}
	
	/**
	 * 执行验证
	 * @throws Exception 
	 */
	@Override
	public void validate() {
		try {
			oph = new ObjectPropertyHelper(this.obj.getClass());
			List<Field> fields = oph.getFields();
			for (Field field : fields) {
				
				String fieldName = field.getName();
				
				// 获取对象中的字段是否有验证注解
				FieldValid validation = oph.getAnnotation(field, FieldValid.class);
				if (validation == null) {
					continue;
				}
				
				String depict = validation.depict();
				
				// 用get方法获取属性的值
				Object value = oph.invokeGetMothod(fieldName, this.obj);
				
				// 验证为空
				if (!validation.nullable()
						&& (value == null || (value instanceof String && StringUtils.isBlank(ObjectUtils.toString(value))))) {
					errors.put(fieldName, StatusConstant.message("13001", depict));
					continue;
				}
				
				if (StringUtils.isNotBlank(ObjectUtils.toString(value))) {
					
					if (value instanceof String) {
						
						// 字符串长度
						int length = validation.length();
						if (ObjectUtils.toString(value).length() > length) {
							errors.put(fieldName, StatusConstant.message("13003", depict, length));
							continue;
						}
						
					}
					
					// 正则验证表达式, 自定义正则优先级高
					String regex = StringUtils.isNotBlank(validation.customRegex()) ? validation.customRegex() : validation.regexType().regex();
					if (StringUtils.isNotBlank(regex)) {
						if (!RegularUtils.matches(regex, ObjectUtils.toString(value))) {
							errors.put(fieldName, StatusConstant.message("13004", depict));
							continue;
						}
					}
					
				}
				
			}
		} catch (Exception e) {
			logger.error("验证器验证失败：", e);
			throw new ValidationException("验证器验证失败", e);
		}
	}
	
	/**
	 * 是否有错误
	 * @return
	 */
	public boolean hasError() {
		return this.errors.size() > 0 ? true : false;
	}
	
	/**
	 * 错误信息
	 * @return
	 */
	public Map<String, String> getErrors() {
		return this.errors;
	}

	public static ValidationHelper valid(Object obj) {
		ValidationHelper helper = new ValidationHelper(obj);
		helper.validate();
		return helper;
	}

}
